/*!
 * tinytree v0.0.6
 * 一个用来展示树状结构的插件
 */

(function($, undefined) {
	;;
	var defaults = {
		data : {},
		title : 'tinytree',
		classes : 'jquery-tinytree',
		
		/**
		 * mode: [ajax,normal,static]
		 * 1.在选择了ajax之后，render方法不接受参数 插件读取ajax.url ajax.method 和 ajax.params参数来实现异步获取树状数据   
		 * 2.normal 则是不提供数据，由render方法传入
		 * 3.static render方法不接受参数，数据由element对象本身提供
		 */
		mode:'normal',
		/**
		 * 异步获取时使用的相关参数
		 * */
		ajax :{
			url:'',
			method:'post',
			params:{},
			dataType:'json',
			rowsLoc:'rows'
		},
		
		/**
		 *输入参数为json时候的处理方式 
		 */
		json :{
			/*字段的标识*/
			Lchildren:'children', /*子数据标识符*/
			Lname:'name', /*显示出来的字段*/
			Lid:'id',
			Lvalue:'value'/*节点数据标识*/
		},
		
		globalCtrls:{
			expandAll:{
				view:'', /*view should be a html-string or a function that returns a html-string*/
				func:function($elem,elem){}
			},
			collapseAll:{
				view:'',
				func:function(){}
			}
		},
		nodeCtrls:{
			
		},
		
		/**
		 * 自定义渲染器
		 */
		leafRenderer:function($a,node){},
		
		on :{
			load:function($elem,elem){},
			expand:function($elem,node){},
			collapse:function($elem,node){},
			select:function($node,node){},
			unselect:function($node,node){}
		},
		
		node:{
			_defaultRenderer:function($node,$view){
				$node.children('a').append($view);
			}
		}
	}
	;;
	var tl = $.tinytree = {
		auther: 'edwinyxc',
		email: 'edwinyxc@gmail.com',
		version : "0.0.3-x86-win32-beta-m1",
		require: 'IE 8.0+, FF 25.0+, CHROME 31.0+',
		remark:''
	};

	/*
	 * v0.0.1
	 * 暂时只有实现了ajax方法
	 */
	$.fn.tinytree = function(options) {
		
		// method calling
		if (typeof options == 'string') {
			var args = Array.prototype.slice.call(arguments, 1);
			var res = '';
			this.each(function() {
				var tinytree = $.data(this, 'tinytree');
				if (tinytree && $.isFunction(tinytree[options])) {
					var r = tinytree[options].apply(tinytree, args);
					if (res === undefined) {
						res = r;
						}
						if (options == 'destroy') {
						$.removeData(this, 'tinytree');
					}
				}
			});
			if (res !== undefined) {
				return res;
			}
			return this;
		}

		$this = $(this);
		this.each(function(i, _element) {
			var element = $(_element);

			;
			var tree = new Tree(element, setDefaults(options));
			element.data('tinytree', tree); // TODO: look into memory leak
			// implications
			tree.render();
		});

		return this;
	};;
	
	var _notEmpty  = function(data){return !!(data && data !== 'null');};
	
	// function for adding/overriding defaults
	function setDefaults(d) {
		return $.extend(true, {}, defaults, d);
	};;

	function Tree($ul, options) {

		var t = this;
		// exports
		t.options = options;
		t.render = render;
		t.refresh = refresh;
		;;
		// imports
		;;
		// locals
		
		var $container = $ul;
		
		function render(){
			switch(options.mode){
				case 'ajax' :ajax(options.ajax);break;
				case 'normal' : renderJson(options.data);break;
				case 'static' : break;//TODO*unfinished*/;
				default: renderJson(options.data);break;	
			}
		}
		
		function renderJson(json){
			json_render_tree(json);
		}
		
		function refresh(ajaxConfig){
			ajax($.extend(true, {}, options.ajax, ajaxConfig));
		}
		
		function ajax(ajaxConfig){
			$.ajax({
				url:ajaxConfig.url,
				type:ajaxConfig.type,
				data:ajaxConfig.params,
				dataType:ajaxConfig.dataType,
				error:function(xhr, status, err){
					if(console && console.log){
						console.log(err);
					}
					alert(err);
				},
				success:function(json,status,xhr){
					if(json){
						var root = json[options.ajax.rowsLoc];
						if(root){
							if($.isArray(root) && root.length)
								renderJson(root[0]);
							else renderJson(root);
						} 
						else{
							if(window && window.console && window.console.log)
								window.console.log('error json not valid');
						}
					}
					//onload
					options.on.load($ul,t,json);
				}
			});
		}
		function render_misc(){
			
		}
		
		function json_render_tree(root_node){
			var $tree = json_render_tree_li(root_node,1);
			$tree.find('a').first().addClass('leader');
			$container
				.empty()
				.append($tree);
			render_misc();
		}
		
		function json_render_tree_li(tree_node,lvl){
			if(tree_node){
				var _lvl = lvl;
				var $li = $('<li></li>'); 
				var name = tree_node[options.json.Lname];
				$li.attr('selected',false);
				$li.data('node',tree_node);
				if(name){
					var $a = $('<a></a>').append('<span class = "name">'+name+'</span>');
					$a.addClass("li_"+_lvl).addClass('anode');
					
					/*a.css('padding-left',(lvl * 20)+'px');*/
					var nodeValue = tree_node[options.json.Lvalue];
					
					if(!!nodeValue){
						for( var v in nodeValue){
							if(!$.isFunction(nodeValue[v])){
								$a.attr(v,nodeValue[v]);
							}
						}
						$li.data('value',nodeValue);
					}
					
					if($.isFunction(options.leafRenderer)){
						/*自定义渲染器*/
						options.leafRenderer($a,tree_node,nodeValue);
					}
					$li.append($a);
					var children = tree_node[options.json.Lchildren];
					if(children && children.length){
						$li.addClass('has_children');
						
						var $children = $('<ul></ul>');
						$li.append($children);
						for(var i = 0 ; i< children.length; i++){
							$children.append(json_render_tree_li(children[i],_lvl+1));
						}
						
						/*
						 * 处理 nodeCtrls
						 */
						for(var i in options.nodeCtrls){
							var ctrl = options.nodeCtrls[i];
							var $view = $(ctrl.view);
							
							var callBack = (function($li,ctrl,view){
								return function(){
									ctrl.func($li,$li.data('node'),view);
								};
							})($li,ctrl,$view);
							$view.bind('click',callBack);
							if(ctrl.render && $.isFunction(ctrl.render)){
								ctrl.render($li,$view);
							}
							else{
								options.node._defaultRenderer($li,$view);
							}
						}
					}
					
					$li.bind('select',function(){
						var $li = $(this);
						$li.attr('selected',true);
						onSelect($li,$li.data('node'));
						if($li.hasClass('has_children')){
							$li.find('ul').find('li').trigger('select');
						}
					});
					
					$li.bind('unselect',function(){
						var $li = $(this);
						$li.attr('selected',false);
						onUnselect($li,$li.data('node'));
						if($li.hasClass('has_children')){
							$li.find('ul').find('li').trigger('unselect');
						}
					});
					
				}
				return $li;
			}
		};
		
		function onSelect($li,node){
			
			/*hook*/
			if($.isFunction(options.on.select))
			options.on.select($li,node);
		}
		
		function onUnselect($li,node){
			
			/*hook*/
			if($.isFunction(options.on.unselect))
			options.on.unselect($li,node);
		}
		
	}
		

})($);
;;
